-- Natur EnemyCastBar Debuffs LUA


-- initialize renew Buff/Debuff system; prepare patterns:
local patterns = {SPELLIMMUNESELFOTHER, SPELLRESISTSELFOTHER, SPELLPARRIEDSELFOTHER, SPELLREFLECTSELFOTHER,
			SPELLBLOCKEDSELFOTHER, SPELLDEFLECTEDSELFOTHER, SPELLDODGEDSELFOTHER, SPELLEVADEDSELFOTHER,
			SPELLMISSSELFOTHER, IMMUNESPELLSELFOTHER };

-- generate miss table out of localized global WoW strings
necb_spellmisses = { };
for k,v in pairs (patterns) do
	necb_spellmisses[k] = "^"..NECB_ConvertPattern(v);
end

function NECB_OnEvent_Debuffs(event)

	if (event == "UNIT_AURA"
		 and ((arg1 == "target" and not CEnemyCastBar.bFocusDebuffsOnly) or (arg1 == "focus" and CEnemyCastBar.bFocusDebuffs))
	) then

		NECB_GatherDebuffsCompensation();

	elseif (event == "CHAT_MSG_SPELL_SELF_DAMAGE") then

		-- spell miss check for ALL languages (created by GlobalStrings.lua in CECB_Debuffs.lua)
		if (necb_fauxtimer[1]) then

			local spell = necb_fauxtimer[2];
			if (necb_fauxtimer[7]) then
				spell = spell ..NECB_Stack_Catcher.. necb_fauxtimer[7]; -- rebuild spell's brackets '(feral)', '(cat)' etc.
			end

			for k,v in pairs (necb_spellmisses) do
				local a,b = string.match(arg1, v);
				if (b) then

					--another check, because some other patterns are catched by 'otherself' with german client
					if ((spell == a and necb_fauxtimer[3] == b) or (spell == b and necb_fauxtimer[3] == a) ) then

						CEnemyCastBar_FauxUpdater("clear");--

							--[[
							local down, up, latency = GetNetStats(); -- debug info
							if ((GetTime() - necb_fauxtimer[1]) > 0.20) then
								down = "|cffffaa00";
							else
								down = "";
							end
							DEFAULT_CHAT_FRAME:AddMessage(down..GetTime() - necb_fauxtimer[1] .. "l: "..latency.." v: "..v.." | "..a..", "..b); -- debug info (time fired: 2 - 9ms!)
							CEnemyCastBar_FauxUpdater("clear");
							return; -- only to prevent message below!
							]]--
							
					end
							--DEFAULT_CHAT_FRAME:AddMessage("|cffff0000PENG: "..GetTime() - necb_fauxtimer[1] .. " v: "..v.." | '"..a.."', '"..b.."'".." 1: "..necb_fauxtimer[2].." 2: "..necb_fauxtimer[3]) --
					return;
				end
			end
		end

	elseif (event == "PLAYER_COMBO_POINTS") then -- need to check before GFind, because has NO arg1 !!

		if (CECBownCPsLast and GetComboPoints() < CECBownCPsLast) then

			CECBownCPsHit = CECBownCPsLast;
			CECBownCPsHitTime = GetTime();

			-- check if there was a finishing move right before you lost all CPs (the server might create a difference up to 500ms between those two events!)
			--CECBownCPsHitBuffer = {mob, spell, GetTime(), DRTimer }; -- just to understand what 1,2,3,4 stands for; defined in 'control' function (affliction)^
			if (CECBownCPsHitBuffer and (CECBownCPsHitTime - CECBownCPsHitBuffer[3]) < 1) then

				local CPSpell = CECBownCPsHitBuffer[2];
				castime = CEnemyCastBar_Afflictions[CPSpell].t - (CEnemyCastBar_Afflictions[CPSpell].cpinterval * (5 - CECBownCPsHit));

				local CPDRTimer = CECBownCPsHitBuffer[4];
				if (CPDRTimer == 4 or CPDRTimer == 6) then
					castime = castime / (CPDRTimer - 2);
				end

				CEnemyCastBar_UniqueCheck(CPSpell, castime - (CECBownCPsHitTime - CECBownCPsHitBuffer[3]), CECBownCPsHitBuffer[1], "trueupdate", nil, nil, "afflictions"); --update bar duration
				CECBownCPsHitTime = false; -- spell already updated no need to wait 1 (before 3) secs for new afflictions
			end
		end
		CECBownCPsLast = GetComboPoints();
		CECBownCPsHitBuffer = false;
		--* p2.1.0 makes so much useless :D check if combopoint system can be left out

	else
		CEnemyCastBar_Gfind_Debuffs(arg1, event);
		-- BIG PARSER!
	end
end

function CEnemyCastBar_PvPCheck(event, necb_unit, spell)
	if (	event
		and string.match("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE", event)
		and not (UnitName(necb_unit) == mob and not UnitIsPlayer(necb_unit)) -- done for mindcontrol always beeing a player event :/
		and not (CEnemyCastBar_Afflictions[spell].spellDR == "PRIEST" and IsInInstance() and not (GetNumBattlefieldStats() > 1 or IsActiveBattlefieldArena() ) ) -- done for mindcontrol always beeing a player event :/
	) then
		return true;
	else
		return false;
	end
end

function CEnemyCastBar_DRBar(drspell, mob, castime, spell, necb_unit, playersclass, icontex)

	local DRTimer = 0;

	if (string.match(drspell, "DR: ") ) then -- update DR DB
		_, DRTimer = CEnemyCastBar_DR_DBCheck(mob, drspell, castime, nil, spell);
	end
	if (CEnemyCastBar_UniqueCheck(drspell, castime, mob, "true",nil,nil,"cooldown") == 0) then
		if (drspell == CECB_SPELL_STUN_DR) then
			CEnemyCastBar_Show(mob, drspell, 15 + castime, "cooldown", nil, "Spell_Frost_Stun", nil, "(|cffff00001/2|r)");
		elseif (UnitName(necb_unit) == mob and playersclass == CEnemyCastBar_Afflictions[spell].spellDR and CEnemyCastBar_UniqueCheck(drspell, castime, mob,nil,nil,nil,"cooldown") == 0) then
			CEnemyCastBar_Show(mob, drspell, 15 + castime, "cooldown", nil, icontex, nil, "(|cffff00001/2|r)");
		end
	elseif (drspell == CECB_SPELL_STUN_DR or (UnitName(necb_unit) == mob and playersclass == CEnemyCastBar_Afflictions[spell].spellDR) ) then
		_, DRTimer = CEnemyCastBar_UniqueCheck(drspell, castime, mob, nil, "trigger label check in uni function",nil,"cooldown");
	end

	return DRTimer;
end

function NECB_Debuffs_Control(mob, spell, special, bcasted, event, rank, stack)

	if (NECB_Debuffs_Module_loaded and CEnemyCastBar.bShowafflict) then

 		-- only 'afflicted', DoTs allowed!
		if (special == "afflicted" or (CEnemyCastBar.bSDoTs and special == "periodicdmg") ) then

			-- initialize locals, since this a separated mod now
			-- Network BC TempBCaster
			local clientlang = GetLocale();	
			-- initialize vars
			local ctype, castime;

 			-- check if spell stacks (number)
			if (stack and not string.match(stack, "%((%d+)%)") ) then
				stack = nil;
			end

			-- check for poison ranks
			for counter=1, #NECB_psuffix do
				if (string.match(spell, NECB_psuffix[counter]) ) then
					spell = string.match(spell, "(.+)"..NECB_psuffix[counter]);
					if (stack) then
						stack = string.match(NECB_psuffix[counter], " (.+)") .. " " .. stack;
					else
						stack = string.match(NECB_psuffix[counter], " (.+)");
					end
					break;
				end
			end

			-- crop the german aposthrophes from some spells (') -- obsolete since patterns are generated from globalstrings

			-- database check + spell filter
			if (CEnemyCastBar_Afflictions[spell]
				and CEnemyCastBar_Afflictions[spell].t

						-- check if previously disabled with shift + leftclick
				and not	(CEnemyCastBar_Afflictions[spell].disabled)
						-- break if 'mage cold debuff' but disabled
				and not	(CEnemyCastBar_Afflictions[spell].magecold and not CEnemyCastBar.bMageC)
						-- periodic dmg spells shall only be triggered if they do damage, otherwise the affliction might be from another player!
				and not	(special == "afflicted" and CEnemyCastBar_Afflictions[spell].periodicdmg)
				and not	(CEnemyCastBar_Afflictions[spell].blockZone and GetRealZoneText() == CEnemyCastBar_Afflictions[spell].blockZone)
						-- don't trigger castbars for your own debuffs if other than boss debuffs
				and not	(mob == UnitName("player") and not CEnemyCastBar_Afflictions[spell].global)
						-- disable normal debuffs if FragOnly is enabled
				and not	(CEnemyCastBar.bFragOnly and not (CEnemyCastBar_Afflictions[spell].fragile or CEnemyCastBar_Afflictions[spell].solo or CEnemyCastBar_Afflictions[spell].periodicdmg or CEnemyCastBar_Afflictions[spell].magecold or CEnemyCastBar_Afflictions[spell].checkclass))

						-- raid debuffs disabled? -- not needed anymore, spells won't load/will be cleared then
				--and not	(CEnemyCastBar_Afflictions[spell].global and not CEnemyCastBar.bBossDebuff)
				--and not	(CEnemyCastBar_Afflictions[spell].aZone and GetRealZoneText() ~= CEnemyCastBar_Afflictions[spell].aZone) -- removed
			) then

				-- special for Paladins Crusader Strike:
				if (CEnemyCastBar_Afflictions[spell].crustrike) then
					NECB_Renew_CStrike_Bars(mob);
				end

				--[[
				-- change name if callspell flag
				if (CEnemyCastBar_Afflictions[spell].callspell) then
					spell = CEnemyCastBar_Afflictions[spell].callspell;
					-- currently only used here for Mage Pet's "Freeze". "Sunder" is changed outside of this function!
				end
				]]-- removed, Freeze got its own bar! TROUBLE: callspells do not have a duration and might cause an error, if it is a detected debuff! So we have to prevent that :D (done)

				local alreadyshowing = 0;
				local icontex = CEnemyCastBar_Afflictions[spell].icontex; -- > get icon texture
				local globalspell = CEnemyCastBar_Afflictions[spell].global; -- > castbars without a target check (Raidencounter)!
				local fragile = CEnemyCastBar_Afflictions[spell].fragile; -- > for option to show "fragiles" without a target!

				if ((UnitName("target") == mob and not CEnemyCastBar.bFocusDebuffsOnly) or (UnitName("focus") == mob and CEnemyCastBar.bFocusDebuffs) or globalspell or (fragile and CEnemyCastBar.bGlobalFrag) or special == "periodicdmg") then

					-- new with NECB 6.9.x, to update focus bars
					local necb_unit = "target";
					if (UnitName("focus") == mob) then
						necb_unit = "focus";
					end

					--
					-- prevent an update by update feature if this is called earlier anyway
					if (special == "afflicted" and CECBFauxFrameButton:IsShown()
						and (necb_fauxtimer[2] == spell)
						and (necb_fauxtimer[3] == mob)
						--and not (necb_fauxtimer[4] and string.match(necb_fauxtimer[4], " (%d+)") ) -- don't delete timer for ranked spells!
					) then
						CEnemyCastBar_FauxUpdater("clear");
						--DEFAULT_CHAT_FRAME:AddMessage("CLEAR");
					end
					--* removed for p2.1.0, no 'notdetected' spells appear in the combatlog, that's why they are notdetected!

					castime = CEnemyCastBar_Afflictions[spell].t;

					local _, playersclass = UnitClass("player");

					-- Collected Debuffs with new UnitDebuff, patch 2.1.0
					if (event and string.match (event, "st:") ) then
						event = GetTime() - string.match (event, "st:(%d+)");
					end

					--
					-- read out possible global rank setting
					if (not rank and necb_block_debuffs[1] and spell == necb_block_debuffs[1] and GetTime() < necb_block_debuffs[2]) then
						rank = necb_block_debuffs[3];
						--DEFAULT_CHAT_FRAME:AddMessage(GetTime() - necb_block_debuffs[2]);
						NECB_set_block_debuff(false);
					end

					-- Consider spell rank to modify duration
					if (rank and not string.match (rank, "d:") ) then
						local lcounter = 2;
						while (CEnemyCastBar_Afflictions[spell].rankmod[lcounter] > rank ) do
							lcounter = lcounter + 1;
						end
						castime = castime - (lcounter - 2)*CEnemyCastBar_Afflictions[spell].rankmod[1];
					end
					--* removed for p2.1.0 + remove rank settings from databases!

					-- Consider player level to modify duration
					if (CEnemyCastBar_Afflictions[spell].plevel and not rank) then
						local lcounter = 2;
						while (CEnemyCastBar_Afflictions[spell].plevel[lcounter] > UnitLevel("player") ) do
							lcounter = lcounter + 1;
						end
						castime = castime - (lcounter - 2)*CEnemyCastBar_Afflictions[spell].plevel[1];
					end

					-- Consider talent points to modify duration
					if (CEnemyCastBar_Afflictions[spell].tskill) then
						local _, _, _, _, currRank = GetTalentInfo(CEnemyCastBar_Afflictions[spell].tskill[1], CEnemyCastBar_Afflictions[spell].tskill[2]);
						if (currRank and currRank > 0 and playersclass == CEnemyCastBar_Afflictions[spell].tskill[4]) then
							if (CEnemyCastBar_Afflictions[spell].tskill[3] ~= 0) then
								castime = castime + currRank*CEnemyCastBar_Afflictions[spell].tskill[3];
							else
								castime = castime * (1 + currRank*CEnemyCastBar_Afflictions[spell].tskill[6] );
							end

							castime = castime + CEnemyCastBar_Afflictions[spell].tskill[5];
						end
					end

					--
					-- Consider Combo points for duration; wait 1 sec for 'Rupture's first DoT damage! (old system was 3 secs)
					if (CEnemyCastBar_Afflictions[spell].cpinterval and playersclass == CEnemyCastBar_Afflictions[spell].cpclass and CECBownCPsHitTime and (GetTime() - CECBownCPsHitTime) < 1) then
						castime = castime - (CEnemyCastBar_Afflictions[spell].cpinterval * (5 - CECBownCPsHit));
						--DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaaNECB:|r Debug, castime="..castime.." -CECBownCPsHit="..CECBownCPsHit.." -cpinterval="..CEnemyCastBar_Afflictions[spell].cpinterval.." -timediff="..GetTime() - CECBownCPsHitTime) 

					end
					--* p2.1.0 makes so much useless :D check if combopoint system can be left out

					if (special == "periodicdmg") then
						ctype = "dots";
					elseif (CEnemyCastBar_Afflictions[spell].stun or CEnemyCastBar_Afflictions[spell].stuntype) then
						ctype = "stuns";
					else
						ctype = "afflict";
					end

					-- PvP event check: outsourced (creates 'no' garbage anymore)
					--CEnemyCastBar_PvPCheck(event, necb_unit, spell);

					-- crowd controlling spells are limited to a 12 sec duration with WoW 2.0 -> 10s with WoW2.2
					if ((CEnemyCastBar_Afflictions[spell].spellDR or CEnemyCastBar_Afflictions[spell].pvpdur)
						and (CEnemyCastBar_PvPCheck(event, necb_unit, spell) or (mob == UnitName(necb_unit) and UnitIsPlayer(necb_unit) ) ) -- and (not UnitIsFriend("player", necb_unit) or UnitReaction("player", necb_unit) < 5)
						and castime > 10
						) then
						if (CEnemyCastBar_Afflictions[spell].pvpdur) then
							castime = CEnemyCastBar_Afflictions[spell].pvpdur;
						else
							castime = 10;
						end
					end

					-- DR START (local function outsourced!)
					
					-- stun diminishing returns bar
					if (CEnemyCastBar.bDRTimer and mob ~= UnitName("player") and CEnemyCastBar_Afflictions[spell].stun) then

						DRTimer = CEnemyCastBar_DRBar(CECB_SPELL_STUN_DR, mob, castime, spell, necb_unit, playersclass, icontex);
					end

					-- pvp diminishing returns bar
					-- playersclass already defined above
					if (CEnemyCastBar.bClassDR and CEnemyCastBar_Afflictions[spell].spellDR and (UnitIsPlayer(necb_unit) or CEnemyCastBar_PvPCheck(event, necb_unit, spell) or CEnemyCastBar_Afflictions[spell].affmob) and mob ~= UnitName("player")) then
						local drshare = CEnemyCastBar_Afflictions[spell].drshare;
						if (drshare) then
							DRTimer = CEnemyCastBar_DRBar("DR: "..drshare, mob, castime, spell, necb_unit, playersclass, icontex);
						else
							DRTimer = CEnemyCastBar_DRBar("DR: "..spell, mob, castime, spell, necb_unit, playersclass, icontex);
						end
					end

					if (DRTimer == 4 or DRTimer == 6) then
						castime = castime / (DRTimer - 2);
					end
					-- DR END

					if (
							-- only show this spell for specified class
							(CEnemyCastBar_Afflictions[spell].checkclass and playersclass ~= CEnemyCastBar_Afflictions[spell].checkclass)
							-- break if 'solo spell' but disabled
						or	(CEnemyCastBar_Afflictions[spell].solo and not CEnemyCastBar.bSoloD)
						) then
						return;
					end

					if (CEnemyCastBar_Afflictions[spell].m) then
					
						mob = CEnemyCastBar_Afflictions[spell].m
					
					end

					local gotdebuffs;
					-- Collected Debuffs with new UnitDebuff, patch 2.1.0
					if (rank and string.match (rank, "d:")) then  --* remove string.match if rank is only called by UnitDebuff with p2.1.0 anyway + rename rank into duration
						castime = tonumber(string.match (rank, "d:(%d+)"));
						gotdebuffs = true;
					end

					-- unique check; Raidspells (globalspell) won't be updated; Fragiles will be updated and multiple bars allowed
					if (fragile or special == "periodicdmg") then
						if (gotdebuffs) then
							if (stack) then
								alreadyshowing = CEnemyCastBar_UniqueCheck(spell,event,mob,"trueupdate","delay"..stack,tonumber(event) + castime,"afflictions");
							else
								alreadyshowing = CEnemyCastBar_UniqueCheck(spell,event,mob,"trueupdate","delay",tonumber(event) + castime,"afflictions");
							end
						else
							alreadyshowing = CEnemyCastBar_UniqueCheck(spell,castime,mob,"trueupdate",nil,nil,"afflictions");
						end
					elseif (stack) then
						if (globalspell) then
							alreadyshowing = CEnemyCastBar_UniqueCheck(spell,castime,mob,"trueupdate",stack,"turnit","afflictions");
						else
							if (gotdebuffs) then
								alreadyshowing = CEnemyCastBar_UniqueCheck(spell,event,mob,nil,"delay"..stack,tonumber(event) + castime,"afflictions");
							else
								alreadyshowing = CEnemyCastBar_UniqueCheck(spell,castime,mob,nil,stack,nil,"afflictions");
							end
						end

					elseif (CEnemyCastBar_Afflictions[spell].multi) then	-- same debuff on target counter
						alreadyshowing = CEnemyCastBar_UniqueCheck(spell,castime,mob,"trueupdate","HoT", nil, "afflictions");
						if (alreadyshowing == 0) then
							alreadyshowing = CEnemyCastBar_UniqueCheck(spell,castime,mob,globalspell,nil,nil,"afflictions"); -- maybe on other mob, update bar for this one then
						end
					else
						if (gotdebuffs) then
							alreadyshowing = CEnemyCastBar_UniqueCheck(spell,event,mob,globalspell,"delay",tonumber(event) + castime,"afflictions");
						else
							alreadyshowing = CEnemyCastBar_UniqueCheck(spell,castime,mob,globalspell,nil,nil,"afflictions");						
						end
					end

					--
					-- to detect if CPs are cleared AFTER a skill has been used, to update with correct duration afterwards if event "PLAYER_COMBO_POINTS" is fired
					if (CEnemyCastBar_Afflictions[spell].cpinterval and playersclass == CEnemyCastBar_Afflictions[spell].cpclass) then
						CECBownCPsHitBuffer = {mob, spell, GetTime(), DRTimer };
					end
					--* p2.1.0 makes so much useless :D check if combopoint system can be left out

					if (globalspell or (fragile and not CEnemyCastBar_PvPCheck(event, necb_unit, spell)) ) then

						-- Network BCasting
						local freetosend, latency = CEnemyCastBar_BCast_Control(bcasted, CEnemyCastBar_Afflictions[spell].crustrike, mob, spell, special );
						if ( freetosend ) then
							local modspell = spell;
							if (stack) then
								modspell = spell..NECB_Stack_Catcher..stack;
							end
							NECB_SendMessage(".cecbspell "..mob..", "..modspell..", "..special..", "..clientlang..", "..latency);
							NECB_set_LastSentBCPacket(mob, modspell, special, GetTime());
							NECB_set_LastGotBCPacket(mob, modspell, special, GetTime());
							necb_numspellcast = 0;
						end
					end

					if (alreadyshowing == 0) then

						-- check if it is a curse then remove old one, because it is another one if we are here
						if (CEnemyCastBar_Afflictions[spell].curse) then

							local minbar, maxbar = 1, CEnemyCastBar.bNumBars;
							if (CEnemyCastBar.bSeparateBars) then
								minbar, maxbar = 6 * CEnemyCastBar.bNumBarsSep + 1, 7 * CEnemyCastBar.bNumBarsSep; --31, 35
							end

							for i=minbar, maxbar do
								local button = getglobal("Carni_ECB_"..i);
								if (CEnemyCastBar_Afflictions[button.spell] and CEnemyCastBar_Afflictions[button.spell].curse and button.mob == mob) then
									CEnemyCastBar_HideBar(i);
								end
							end
						end

						-- turnaroundlabel through "globalspell" (turnlabel), because the name is more important then

						-- 8 5 7 +: new code to color fragiles of group members
						if (CEnemyCastBar_Afflictions[spell].fragile) then
							local start, myunit = GetNumPartyMembers(), "party";
							if (GetNumRaidMembers() ~= 0) then
								start, myunit = GetNumRaidMembers(), "raid";
							end

							for i=1,start do
								if ( UnitName(myunit .. i) == mob ) then
									globalspell = true; -- not needed for anything else than "show" from here downwards
									break;
								end
							end
						end -- finished color and turnaround

						CEnemyCastBar_Show(mob, spell, castime, ctype, globalspell, icontex, event, stack); -- event sets possible time past from UnitDebuff gather
					end
				end

			end -- is spell in database?
	 	end -- check for afflicted/ DoTs option + periodicdmg

	end -- clear on mob fades/dies, elseif check option, afflictions set on?
	------ block end (afflictions+)

end


function NECB_Renew_CStrike_Bars(mob)

	local firstbutton = 1;
	local lastbutton = CEnemyCastBar.bNumBars;
	if (CEnemyCastBar.bSeparateBars) then
		firstbutton = 4 * CEnemyCastBar.bNumBarsSep + 1; --21
		lastbutton = 7 * CEnemyCastBar.bNumBarsSep; --35
	end

	for i=firstbutton, lastbutton do

		local button = getglobal("Carni_ECB_"..i);
		if (button.mob == mob and button.spell and CEnemyCastBar_Afflictions[button.spell] and CEnemyCastBar_Afflictions[button.spell].judgement) then

			if (GetTime() - button.startTime > 1) then --* p2.1.0 only update if difference is high enough
				button.startTime = GetTime();
				button.endTime = button.startTime + CEnemyCastBar_Afflictions[button.spell].t;
				getglobal("Carni_ECB_"..i.."_StatusBar"):SetMinMaxValues(button.startTime, button.endTime);
			end
		end
	end

end


function CEnemyCastBar_DR_DBCheck(mob, spell, castime, msg, realspell) --DR Check

	local i = 1;

	-- update on spellfade
	if (msg) then -- "fadeupdate"
		while i <= #NECB_DR_DB do
	
			if ( NECB_DR_DB[i][1] == mob and NECB_DR_DB[i][2] == spell ) then
	
				NECB_DR_DB[i][3] = GetTime();
				NECB_DR_DB[i][4] = castime;
				--DEFAULT_CHAT_FRAME:AddMessage("FadeUpdate Mob: "..mob.." |Spell: "..spell);
			end
			i = i + 1;
		end
		return;
	end

	local ashowing, drstate = 0, 0;
	local DRText;
	local DRDBUpdated = false;
	-- add DR to database
	while i <= #NECB_DR_DB do
		if ( GetTime() > ( NECB_DR_DB[i][3] + NECB_DR_DB[i][4] ) ) then
			table.remove(NECB_DR_DB, i);
			i = i - 1;
			--DEFAULT_CHAT_FRAME:AddMessage("Removed Mob: "..mob.." |Spell: "..spell);

		elseif ( NECB_DR_DB[i][1] == mob and NECB_DR_DB[i][2] == spell ) then

			DRText = NECB_DR_DB[i][5];
			if (string.match(DRText, "1/2")) then
				drstate = 4; DRText = "(|cffff00001/4|r)"; castime = castime/2 + 15;
			elseif (string.match(DRText, "1/4")) then
				drstate = 6; DRText = "(|cffff0000"..CECB_MISC_IMMUNE.."|r)"; castime = castime/4 + 15;
			elseif (string.match(DRText, CECB_MISC_IMMUNE)) then
				drstate = 2; DRText = "(|cffff00001/2|r)"; castime = castime + 15;
			end

			NECB_DR_DB[i][3] = GetTime();
			NECB_DR_DB[i][4] = castime;
			NECB_DR_DB[i][5] = DRText;
			DRDBUpdated = true;
			--DEFAULT_CHAT_FRAME:AddMessage("Updated Mob: "..mob.." |Spell: "..spell.." dr: "..drstate);
		end
		i = i + 1;
	end

	if ( not DRDBUpdated and #NECB_DR_DB < 15) then
		drstate = 2; DRText = "(|cffff00001/2|r)"; castime = castime + 15;
		table.insert(NECB_DR_DB, { mob, spell, GetTime(), castime, DRText, realspell } );
		--DEFAULT_CHAT_FRAME:AddMessage("Added Mob: "..mob.." |Spell: "..spell.." Nr.:"..#NECB_DR_DB);
	end
	return DRDBUpdated, drstate;

end

local NECB_gathdb_unit = {"focus", "target"};
function NECBGatherDebuffs() --getdebuffs

	if (UnitAffectingCombat("player") ) then

		local name, count, duration, timeLeft;

		local gounits, endunits = 2,2;
		if (CEnemyCastBar.bFocusDebuffsOnly) then
			gounits, endunits = 1,1;
		elseif (CEnemyCastBar.bFocusDebuffs and UnitExists("focus") and not UnitIsUnit("target", "focus") ) then
			gounits = 1;
		end -- update focus first, otherwise normal debuffs of target will be overridden by focus unit's name! Might produce strange bar behavior in some cases...

		for u=gounits, endunits do

			local i = 1;
			while UnitDebuff(NECB_gathdb_unit[u], i) do
				name, _, _, count, _, duration, timeLeft = UnitDebuff(NECB_gathdb_unit[u], i);

				if (timeLeft) then

					name = string.gsub(name, NECB_Stack_Catcher2, ""); -- remove any brackets in NAME

		 			-- check if spell has poison suffix
					local pstack = "";
					for counter=1, #NECB_psuffix do
						if (string.match(name, NECB_psuffix[counter]) ) then
							name = string.match(name, "(.+)"..NECB_psuffix[counter]);
							pstack = NECB_psuffix[counter];
							break;
						end
					end

					if (
						CEnemyCastBar_Afflictions[name]
						and not CEnemyCastBar_Afflictions[name].multi --will show/renew the bar anyway
						--and not (CEnemyCastBar_Afflictions[name].stun or CEnemyCastBar_Afflictions[name].stuntype) --don't get info for stuns, experimentally commented out
						and not (CEnemyCastBar_Afflictions[name].disabled)
						and not (CEnemyCastBar_Afflictions[name].magecold and not CEnemyCastBar.bMageC)
					) then


						-- reduce control-calls with this + filter above:
						local minbar, maxbar = 1, CEnemyCastBar.bNumBars;
						if (CEnemyCastBar.bSeparateBars) then
							minbar, maxbar = 4 * CEnemyCastBar.bNumBarsSep + 1, 7 * CEnemyCastBar.bNumBarsSep; -- stuns, affl, periodic; stuns, too? checkout
						end
			
						local spellgood;
							--DEFAULT_CHAT_FRAME:AddMessage("UnitDebuff")
						for i=minbar, maxbar do
							local bar = getglobal("Carni_ECB_"..i);
		
							if (	bar.spell 
								and name == bar.spell
								and not (CEnemyCastBar_Afflictions[name].fragile and bar.mob ~= UnitName(NECB_gathdb_unit[u]) )
		
							) then
									--DEFAULT_CHAT_FRAME:AddMessage("spellgood = true: "..bar.spell)
								spellgood = true;

 								-- change bars name to name of focus/target always
								if (bar.mob ~= UnitName(NECB_gathdb_unit[u]) and (bar.ctype == "afflict" or bar.ctype == "stuns") ) then
									bar.mob = UnitName(NECB_gathdb_unit[u]);
									bar.label = string.gsub(bar.label, "- (.+)", "- "..bar.mob);
									bar.updlabel = true;
								end

								if (math.abs((bar.endTime - GetTime()) - timeLeft) > 1 ) then -- only update bar if difference is too much to reduce 'control' calls
									spellgood = false;
									--DEFAULT_CHAT_FRAME:AddMessage("spellgood = false")

								elseif ( (count > 1 and tonumber(bar.stack) ~= count)
										or (count == 1 and tonumber(bar.stack) == 2) -- fix for stormstrike (counts down!)
								) then
	 								-- update stack, too! It will be called as own (second) event directly after the Debuff has been applied!
									if (count == 1) then
										bar.stack = false; -- fix for stormstrike (counts down!)
									else
										bar.stack = count;
									end

									if (CEnemyCastBar.bShowIcon) then
										getglobal("Carni_ECB_"..i.."_IconStack"):SetText(bar.stack);
									else

										if (bar.stack) then
											if (bar.ctype == "dots" and CEnemyCastBar.bturnDoTs) then
												bar.label = bar.mob.." - "..bar.spell..pstack.." ("..count..")";
											else
												bar.label = bar.spell..pstack.." ("..count..")".." - "..bar.mob;
											end
										else
											if (bar.ctype == "dots" and CEnemyCastBar.bturnDoTs) then
												bar.label = bar.mob.." - "..bar.spell..pstack;
											else
												bar.label = bar.spell..pstack.." - "..bar.mob;
											end
										end
										bar.updlabel = true;
									end
								end
								break;
							end
						end
		
						if (not spellgood) then
								--DEFAULT_CHAT_FRAME:AddMessage("if not spellgood")
							local type = "afflicted";
							if (CEnemyCastBar_Afflictions[name].periodicdmg) then
								type = "periodicdmg";
							end
		

							if (pstack ~= "") then
								name = name..pstack; -- rebuild poison level, has to be decoded for combatlog events anyway
							end

							if (count > 1) then
								count = "("..count..")";
							else
								count = nil;
							end

							CEnemyCastBar_Control(UnitName(NECB_gathdb_unit[u]), name, type, nil, "st:"..(duration - timeLeft), "d:"..duration, count); -- time past
								--DEFAULT_CHAT_FRAME:AddMessage(UnitName(NECB_gathdb_unit[u])..", "..name..", "..(duration - timeLeft)..", d:"..duration..", "..count)
						end
					end
				else
					break;
				end
				i = i + 1;
			end -- while .. end
		end
	end

end


function NECB_GatherDebuffsCompensation()

	if (GetNumRaidMembers() == 0 or (GetTime() - NECB_Debuff_grabber > 0.25) ) then -- variable set in register-func, before trigger-event can be fired
		--DEFAULT_CHAT_FRAME:AddMessage("Ping")
		NECB_Debuff_grabber = GetTime(); -- initially set with Debuff module loaded
		NECBGatherDebuffs();
	end
end


--[[

SPELLIMMUNESELFOTHER = "%1$s war ein Fehlschlag. %2$s ist immun.";
SPELLRESISTSELFOTHER = "Ihr habt es mit %1$s versucht, aber %2$s hat widerstanden.";

SPELLPARRIEDSELFOTHER = "%1$s wurde von %2$s pariert.";
SPELLREFLECTSELFOTHER = "%1$s wurde von %2$s reflektiert.";
SPELLBLOCKEDSELFOTHER = "%1$s wurde von %2$s geblockt.";
SPELLDEFLECTEDSELFOTHER = "%1$s wurde von %2$s abgewehrt.";

SPELLDODGEDSELFOTHER = "%2$s ist %1$s ausgewichen.";
SPELLEVADEDSELFOTHER = "%2$s ist %1$s entkommen.";

SPELLMISSSELFOTHER = "%1$s hat %2$s verfehlt.";

IMMUNESPELLSELFOTHER = "%1$s ist immun gegen %2$s von Euch.";
--
SPELLLOGABSORBSELFOTHER = "Euer Zauber %1$s wurde von %2$s absorbiert.";
PROCRESISTSELFOTHER = "%1$s widersteht %2$s.";

VSABSORBSELFOTHER = "Ihr greift an. %s absorbiert allen Schaden.";
VSBLOCKSELFOTHER = "Ihr greift an. %s blockt ab.";
VSDEFLECTSELFOTHER = "Ihr greift an. %s wehrt ab.";
VSDODGESELFOTHER = "Ihr greift an. %s weicht aus.";
VSEVADESELFOTHER = "Ihr greift an. %s entkommt.";
VSIMMUNESELFOTHER = "Ihr greift an, aber %s ist immun.";
VSPARRYSELFOTHER = "Ihr greift an. %s pariert.";,
VSRESISTSELFOTHER = "Ihr greift an. %s widersteht dem gesamten Schaden.";
IMMUNEDAMAGECLASSSELFOTHER = "%1$s ist immun gegen Euren %2$sschaden.";
]]--just to have a look later


NECB_Debuffs_Module_loaded = true;
--NECB_InfoFrame:AddMessage("|cffaaaaaaNECB:|r Debuffs Module loaded into memory!", 1, 0.5, 0, 1, UIERRORS_HOLD_TIME);